package com.tbi.graphcolouring.utils;

public class Random {

    /**
     * Return a real number from an exponential distribution with rate lambda.
     */
	public static double exponential(double lambda) {
        return -Math.log(1 - uniform()) / lambda;
    }
    
    public static double scaledExponential(int scale) {
		double random = Math.abs(exponential(6)) * scale;
		
		while(random >= scale){
			random = Math.abs(exponential(6)) * scale;
		}
		return random;
	}

    /**
     * Return a real number with a standard Gaussian distribution.
     */
    public static double gaussian() {
        // use the polar form of the Box-Muller transform
        double r, x, y;
        do {
            x = uniform(-1.0, 1.0);
            y = uniform(-1.0, 1.0);
            r = x*x + y*y;
        } while (r >= 1 || r == 0);
        return x * Math.sqrt(-2 * Math.log(r) / r);

        // Remark:  y * Math.sqrt(-2 * Math.log(r) / r)
        // is an independent random gaussian
    }

    /**
     * Return a real number from a gaussian distribution with given mean and stddev
     */
    public static double gaussian(double mean, double stddev) {
        return mean + stddev * gaussian();
    }
    
    public static double scaledGaussian(int scale) {
		double random = Math.abs(gaussian(0., 0.3)) * scale;
		
		while(random >= scale){
			random = Math.abs(gaussian(0., 0.3)) * scale;
		}
		return random;
	}

    /**
     * Return real number uniformly in [a, b).
     */
    public static double uniform(double a, double b) {
        return a + uniform() * (b-a);
    }

    /**
     * Return real number uniformly in [0, 1).
     */
    public static double uniform() {
        return Math.random();
    }
    
    public static boolean checkSuccess(double chance){
    	return uniform() < chance;
    }
}
